<template>
  <div class="q-mx-md q-mt-sm text-bold bg-white">当前页面：{{canvas.cname}}</div>
  <q-scroll-area style="height: 600px; max-width: 1000px;">
    <div
      class="my-container"
      :style="{
      width: store.canvas.width,
      height: store.canvas.height,
      backgroundColor: store.canvas.backgroundColor,
      backgroundImage: `url(${store.canvas.backgroundImage})`
    }"
    >
      <DraggableContainer
        tabindex="-1"
        hidefocus="true"
        id="editor-canvas"
        class="my-draggable-container"
        :adsorbRows="[10,20,30]"
        :adsorbCols="[10,20,30]"
        @drop="onCanvasDrop($event)"
        @dragover.prevent
        @mousedown.stop="onCanvasMouseDown($event)"
        @mouseup="onCanvasMouseUp($event)"
        @mousemove="onCanvasMouseMove($event)"
        @keydown.ctrl.c.stop="onCanvasCopied()"
        @keydown.ctrl.v.stop="onCanvasPasted()"
        @keydown.delete.stop="onCanvasDeleted()"
        @keydown.up.stop="onCanvasMoved(EnumEditorEvent.EDITOR_KEY_EVT_UP_MOVE)"
        @keydown.down.stop="onCanvasMoved(EnumEditorEvent.EDITOR_KEY_EVT_DOWN_MOVE)"
        @keydown.left.stop="onCanvasMoved(EnumEditorEvent.EDITOR_KEY_EVT_LEFT_MOVE)"
        @keydown.right.stop="onCanvasMoved(EnumEditorEvent.EDITOR_KEY_EVT_RIGHT_MOVE)"
        @keydown.esc.stop="onCanvasCanceled()"
      >
        <template v-for="(component, index) in store.components" :key="component.sid">
          <Vue3DraggableResizable
            :initW="component.position.w"
            :initH="component.position.h"
            v-model:x="component.position.x"
            v-model:y="component.position.y"
            v-model:w="component.position.w"
            v-model:h="component.position.h"
            v-model:active="store.componentState[index].selected"
            :parent="true"
            :draggable="true"
            :resizable="true"
            @activated="onComponentSelected(component.comSid)"
            @drag-start="onComponentDragStarted(component.position.x, component.position.y, component.comSid)"
            @resize-start="print('resize-start')"
            @dragging="onComponentDragging(component.position.x, component.position.y)"
            @resizing="print('resizing')"
            @drag-end="print('drag-end')"
            @resize-end="print('resize-end')"
            @mousedown.stop="onComponentMousedown(component.comSid)"
            @click.stop
            :style="{
              zIndex: component.shape.zIndex,
              transform: component.shape.transform? `rotate(${component.shape.transform}deg)`:'rotate(0deg)',
            }"
          >
            <component
              :is="parseView(component)"
              :detail="component"
            />

          </Vue3DraggableResizable>
        </template>
        <div
          class="my-rect-selection"
          :style="{
            width: selectionRect.w + 'px',
            height: selectionRect.h + 'px',
            top: selectionRect.y + 'px',
            left: selectionRect.x + 'px',
            zIndex: 999
        }"
        />
      </DraggableContainer>
    </div>
  </q-scroll-area>
</template>

<script lang="ts">

import { defineComponent, onMounted, onUnmounted, watch, reactive, computed } from 'vue';
import Vue3DraggableResizable, { DraggableContainer } from 'vue3-draggable-resizable'
import 'vue3-sketch-ruler/lib/style.css'
import 'vue3-draggable-resizable/dist/Vue3DraggableResizable.css'
import { parseViewName } from '../../hook/common/useComponentParse';
import { CPosition, CGraphEntity, EnumEditorEvent, CPoint, EPageType } from 'stores/editorModels';
import { useSelectedTuple } from 'src/hook/editor/useSelectedTuple';
import { useEditorCreateComponent } from 'src/hook/editor/useEditorCreateComponent';
import { useEditorExecPageComponents } from 'src/hook/editor/useEditorExecPageComponents';
import { useEditorStore } from 'stores/editorStore';
import { storeToRefs } from 'pinia';
import BaseComponent from 'components/views/BaseComponent.vue';
import { useEditorEvent } from 'src/hook/editor/useEditorEvent';
import { useRoute } from 'vue-router';
import { useEditorExecModPageComponent } from 'src/hook/editor/useEditorExecModPageComponent';
import { useCommonStore } from 'stores/commonStore';
import { CSocket } from 'socket/websocket'

export default defineComponent({
  name: 'MainEditor',
  extends: BaseComponent,
  components: {
    Vue3DraggableResizable,
    DraggableContainer
  },
  setup (props, context) {
    //*********************************************************
    //          route
    //*********************************************************
    //router是全局路由对象，route是当前路由对象
    let curRoute = useRoute();

    //*********************************************************
    //          store
    //*********************************************************
    //store
    const commonStore = useCommonStore();
    const store = useEditorStore();
    const {
      project,
      pageType,
      canvas,
      components,
      componentState,
      selectedComponent,
      selectedList,
      deletedList,
      copiedList,
      moveComponent
    } = storeToRefs(store);

    //*********************************************************
    //                    标尺
    //*********************************************************
    const rectWidth = 600;
    const rectHeight = 320;
    let state = reactive({
      scale: 0.75, //658813476562495, //1,
      startX: 0,
      startY: 0,
      lines: {
        h: [433, 588],
        v: [33, 143]
      },
      thick: 20,
      isShowRuler: true, // 显示标尺
      isShowReferLine: false // 显示参考线
    });

    let shadow = computed(() => {
      return {
        x: 0,
        y: 0,
        width: rectWidth,
        height: rectHeight
      }
    })

    let canvasStyle = computed(() => {
      return {
        width: rectWidth,
        height: rectHeight,
        transform: `scale(${state.scale})`
      }
    })

    //*********************************************************
    // 实现拖拽生成组件、保存组件、删除组件、更新页面组件
    //*********************************************************
    const {
      createComponent
    } = useEditorCreateComponent();

    //*********************************************************
    // 当前页面组件读写
    //*********************************************************
    const {
      getCurrentPageInfo
    } = useEditorExecPageComponents();


    const {
      getModuleCurrentPage
    } = useEditorExecModPageComponent();

    //*********************************************************
    //                    画布鼠标、键盘事件
    //*********************************************************
    const {
      selectionRect,
      isHasSelectedTuple,
      clearSelectedTuple,

      setRectSelectionTuple,
      getRectSelectionTuple,
      clearRectSelectionTuple
    } = useSelectedTuple();

    const {
      removeSelectedItems,
      moveSelectedItems,
      copySelectedItems,
      pasteSelectedItems,
      cancelSelectedItems
    } = useEditorEvent();

    //鼠标事件按下标识
    let isMouseDown = false;

    // 拖拽事件
    const onCanvasDrop = (event: DragEvent) => {
      //阻止冒泡
      event.preventDefault();
      if (event.dataTransfer !== null) {
        let rect: CPosition = {
          x: 0,
          y: 0,
          w: 0,
          h: 0
        };

        //判断当前着陆点是不是在画布内
        let el = document.getElementById('uiv-canvas');
        if (event.target as HTMLElement === el) {
          rect.x = event.offsetX; //offset是鼠标相对于目标元素的坐标
          rect.y = event.offsetY;
        } else {
          let layer = event.currentTarget as HTMLDivElement;
          let position = layer.getBoundingClientRect();
          rect.x = event.clientX - position.x;
          rect.y = event.clientY - position.y;
        }

        let component_id = event.dataTransfer.getData('component-create');
        let pageId = curRoute.query.pageId as any;
        if (isNaN(pageId)) {
          pageId = 0;
        }

        //读取数据模型
        createComponent(parseInt(component_id),  pageId);
        //console.log('create component');

        //编辑区界面获取焦点，响应鼠标和按键事件
        el?.focus();
      }
    };

    //画布上鼠标按下事件
    const onCanvasMouseDown = (ev: MouseEvent) => {
      //取消所有选择，即将面来选择做准备，框选、单选、ctrl+单击多选
      if (!isMouseDown) {
        print('canvas mousedown')
        setRectSelectionTuple(ev);
        isMouseDown = true;
      }
    }

    //画布上鼠标按下事件
    const onCanvasMouseMove = (ev: MouseEvent) => {
      // 矩形选中还是移动
      if (isMouseDown) {
        print('canvas mousemove');
        getRectSelectionTuple(ev);
      }
    }

    //画布上鼠标松开事件
    const onCanvasMouseUp = (ev: MouseEvent) => {
      //选择框取消
      if (isMouseDown) {
        print('canvas mouseup');
        clearSelectedTuple();
        getRectSelectionTuple(ev);
        clearRectSelectionTuple();
        isMouseDown = false;
      }
    }


    //拷贝事件CTRL+C
    const onCanvasCopied = () => {
      copySelectedItems();
      //print('ctrl+c');
    }

    //粘贴事件CTRL+V
    const onCanvasPasted = () => {
      pasteSelectedItems();
      //print('ctrl+v');
    }

    //键盘delete
    const onCanvasDeleted = () => {
      removeSelectedItems();
      //print('delete key');
    }

    //方向键UP,DOWN,LEFT,RIGHT
    const onCanvasMoved = (evt: EnumEditorEvent) => {
      moveSelectedItems(evt);
      print('direction key');
    }

    //取消ESC
    const onCanvasCanceled = () => {
      cancelSelectedItems();
      //print('esc key');
    }

    //*********************************************************
    //                    组件鼠标、键盘事件
    //*********************************************************
    //选择事件
    const onComponentSelected = (sid: string) => {
      //store.componentState[index].selected = true;
      store.addSelectedComponent(sid);
    }

    //取消选择事件
    const onComponentUnselected = (sid: string) => {
      //print('deactived:' + activeStatus.value);
    }

    //组件开始拖动
    const onComponentDragStarted = (px: number, py: number, sid: string) => {
      let position: CPoint = {
        x: px,
        y: py
      };

      //记录初始位置
      store.initSelectedComponentPosition(position, sid);
    }

    //组件拖动中
    const onComponentDragging = (x: number, y: number) => {
      store.moveSelectedComponentPosition();
    }

    //组件单击
    const onComponentMousedown = (sid: string) => {
      store.addSelectedComponent(sid);
      print('mousedown')
    }

    //事件函数
    const print = (s: string) => {
      console.log(s);
    }

    //*********************************************************
    //          动态组件解析
    //*********************************************************
    // 依据名称解析成vue组件
    const parseView = (com: CGraphEntity) => {
      return parseViewName(com);
    };

    //*********************************************************
    //          初始化
    //*********************************************************
    //初始化
    const init = () => {
      //根据路由获取当前信息，项目信息
      if (curRoute.query.projectId) {
        let id = parseInt(curRoute.query.projectId as any);
        if (!isNaN(id)) {
          //console.log(curRoute.query.projectName);
          let name = curRoute.query.projectName as string;
          store.setProject(id, name);
        }
      }

      //页面类型信息，空，模板、新建、已存在
      //console.log(curRoute.query);
      if ((curRoute.query.pageType) && (curRoute.query.pageId)) {
        let pageType = parseInt(curRoute.query.pageType as string);
        let pageId = parseInt(curRoute.query.pageId as string);
        if ((!isNaN(pageType)) && (!isNaN(pageId))) {
          store.setPage(pageType, pageId);
        }
      }

      //读取页面信息
      if ((store.pageType === EPageType.EXIST_PAGE) && (store.canvas.id > 0)) {
        getCurrentPageInfo();
      } else if ((store.pageType === EPageType.MOD_PAGE) && (store.canvas.id > 0)) {
        getModuleCurrentPage();
      }

      //属性框显示
      commonStore.setRightDrawer(true);
    }

    //监视界面变化
    watch(() => curRoute.query, () => {
      init();
    });

    //*********************************************************
    //          启动
    //*********************************************************
    //组件挂载
    onMounted(() => {
      init();
    });

    //组件卸载
    onUnmounted(() => {
      store.initCanvas();
      store.initComponents();
    })

    return {
      store,
      project,
      pageType,
      canvas,
      components,
      selectedComponent,
      componentState,
      selectedList,
      deletedList,
      copiedList,
      moveComponent,

      state,
      shadow,
      canvasStyle,

      selectionRect,
      isHasSelectedTuple,
      onCanvasMouseDown,
      onCanvasMouseMove,
      onCanvasMouseUp,
      onCanvasCopied,
      onCanvasPasted,
      onCanvasDeleted,
      onCanvasMoved,
      onCanvasCanceled,

      onComponentSelected,
      onComponentUnselected,
      onComponentDragStarted,
      onComponentDragging,
      onComponentMousedown,
      print,


      parseView,
      onCanvasDrop,

      EnumEditorEvent,
      curRoute
    };
  }
});

</script>

<style lang="scss" scoped>
.my-tool {
  margin: 1px;
  padding: 1px;
}

.my-container {
  margin: 1px;
  padding: 2px;
  width: 100%;
  height: calc(100vh - 50px);
  position: relative;

  background-color: white;
  background-size: 100%;
  background-repeat: no-repeat;

  .my-draggable-container {
    outline: none;
    cursor: default;
  }

  .my-rect-selection {
    background-color: #e787a9;
    opacity: 0.3;
    border: #0000ff solid 1px;
    position: absolute;
    z-index: 999;
  }
}
</style>
